package com.example.servicearea.dahua;


import com.example.servicearea.lib.NetSDKLib;

import com.example.servicearea.lib.ToolKits;

import com.sun.jna.Pointer;

import java.io.File;


public class SDKUtil{

    public static NetSDKLib netsdk = NetSDKLib.NETSDK_INSTANCE;
    public static NetSDKLib configSdk = NetSDKLib.CONFIG_INSTANCE;


    // 设备信息
    public static NetSDKLib.NET_DEVICEINFO_Ex m_stDeviceInfo = new NetSDKLib.NET_DEVICEINFO_Ex();


    private static boolean bLogopen = true;



    public static void init() {
        System.out.println("initial***********");

        // 初始化SDK库
        netsdk.CLIENT_Init(DisConnectCallBack.getInstance(), null);

        // 设置断线重连成功回调函数
        netsdk.CLIENT_SetAutoReconnect(HaveReConnectCallBack.getInstance(), null);

        //打开日志，可选
        NetSDKLib.LOG_SET_PRINT_INFO setLog = new NetSDKLib.LOG_SET_PRINT_INFO();
        String logPath = new File(".").getAbsoluteFile().getParent() + File.separator + "sdklog" + File.separator + "sdk.log";
        setLog.bSetFilePath = 1;
        System.arraycopy(logPath.getBytes(), 0, setLog.szLogFilePath, 0, logPath.getBytes().length);
        setLog.bSetPrintStrategy = 1;
        setLog.nPrintStrategy = 0;
        if (!netsdk.CLIENT_LogOpen(setLog)) {
            System.err.println("Open SDK Log Failed!!!");
        }
    }

    /**
     * 清除环境
     */
    public static void cleanup() {
        if (bLogopen) {
            netsdk.CLIENT_LogClose();
        }

    }

//    /**
//     * 登录设备
//     */
    public static NetSDKLib.LLong login(String m_strIp, int m_nPort, String m_strUser, String m_strPassword) {

        NetSDKLib.NET_IN_LOGIN_WITH_HIGHLEVEL_SECURITY pstInParam=
                new NetSDKLib.NET_IN_LOGIN_WITH_HIGHLEVEL_SECURITY();

        pstInParam.szIP= m_strIp.getBytes();
        pstInParam.nPort= m_nPort;
        pstInParam.szUserName= m_strUser.getBytes();
        pstInParam.szPassword= m_strPassword.getBytes();
        //出参
        NetSDKLib.NET_OUT_LOGIN_WITH_HIGHLEVEL_SECURITY pstOutParam=
                new NetSDKLib.NET_OUT_LOGIN_WITH_HIGHLEVEL_SECURITY();
        NetSDKLib.LLong m_hLoginHandle =
                netsdk.CLIENT_LoginWithHighLevelSecurity(
                        pstInParam,  pstOutParam);
        if(m_hLoginHandle.longValue() == 0) {
            System.err.printf("Login Device[%s] Port[%d]Failed. %s\n", m_strIp, m_nPort,
                    ToolKits.getErrorCodePrint());
        } else {
//            System.out.println("Login Success ");
        }
        return m_hLoginHandle;

    }



    /**
     * 登出设备
     */
    public static boolean logout(NetSDKLib.LLong m_hLoginHandle) {
        if (m_hLoginHandle.longValue() == 0) {
            return false;
        }

        boolean bRet = netsdk.CLIENT_Logout(m_hLoginHandle);
        if (bRet) {
            m_hLoginHandle.setValue(0);
        }

        return bRet;
    }

    // Attach 订阅 人数统计事件
    public static NetSDKLib.LLong attachPersonSummary(int channel, NetSDKLib.LLong m_hLoginHandle, NetSDKLib.fVideoStatSumCallBack fVideoStatSumCallBack) {

        NetSDKLib.NET_IN_ATTACH_VIDEOSTAT_SUM inParam = new NetSDKLib.NET_IN_ATTACH_VIDEOSTAT_SUM();
        inParam.nChannel = channel;
        inParam.cbVideoStatSum = fVideoStatSumCallBack;

        NetSDKLib.NET_OUT_ATTACH_VIDEOSTAT_SUM outParam = new NetSDKLib.NET_OUT_ATTACH_VIDEOSTAT_SUM();
        NetSDKLib.LLong m_hAttachHandle = netsdk.CLIENT_AttachVideoStatSummary(m_hLoginHandle, inParam, outParam, 5000);

        //打开日志，可选
        NetSDKLib.LOG_SET_PRINT_INFO setLog = new NetSDKLib.LOG_SET_PRINT_INFO();
        File path = new File("./sdklog/");
        if (!path.exists()) {
            path.mkdir();
        }
        String logPath = path.getAbsoluteFile().getParent() + "\\sdklog\\sdk.log";
        setLog.nPrintStrategy = 0;
        setLog.bSetFilePath = 1;
        System.arraycopy(logPath.getBytes(), 0, setLog.szLogFilePath, 0, logPath.getBytes().length);
        System.out.println(logPath);
        setLog.bSetPrintStrategy = 1;
        bLogopen = netsdk.CLIENT_LogOpen(setLog);
        if (!bLogopen) {
            System.err.println("Failed to open NetSDK log");
        }

        if (m_hAttachHandle.longValue() == 0) {
            System.err.printf("Attach Failed!LastError = %s\n", ToolKits.getErrorCodePrint());
            return m_hAttachHandle;
        }
        System.out.printf("Attach Succeed at Channel %d ! AttachHandle: %d. Wait Device Notify Information\n", channel, m_hAttachHandle.longValue());
        return m_hAttachHandle;
    }


    //订阅车流事件
    public static NetSDKLib.LLong attachVehicleSummary(int channel, NetSDKLib.LLong m_hLoginHandle, NetSDKLib.fAnalyzerDataCallBack fVideoStatSumCallBack) {

        NetSDKLib.NET_IN_ATTACH_VIDEOSTAT_SUM inParam = new NetSDKLib.NET_IN_ATTACH_VIDEOSTAT_SUM();
        inParam.nChannel = channel;
        inParam.cbVideoStatSum = fVideoStatSumCallBack;

        NetSDKLib.NET_OUT_ATTACH_VIDEOSTAT_SUM outParam = new NetSDKLib.NET_OUT_ATTACH_VIDEOSTAT_SUM();
        //NetSDKLib.LLong m_hAttachHandle = netsdk.CLIENT_AttachVideoStatSummary(m_hLoginHandle, inParam, outParam, 5000);

        NetSDKLib.LLong m_hAttachHandle  = netsdk.CLIENT_RealLoadPictureEx(m_hLoginHandle,channel,NetSDKLib.EVENT_IVS_ALL,
                1,fVideoStatSumCallBack,null,null);



        //打开日志，可选
        NetSDKLib.LOG_SET_PRINT_INFO setLog = new NetSDKLib.LOG_SET_PRINT_INFO();
        File path = new File("./sdklog/");
        if (!path.exists()) {
            path.mkdir();
        }
        String logPath = path.getAbsoluteFile().getParent() + "\\sdklog\\sdk.log";
        setLog.nPrintStrategy = 0;
        setLog.bSetFilePath = 1;
        System.arraycopy(logPath.getBytes(), 0, setLog.szLogFilePath, 0, logPath.getBytes().length);
        System.out.println(logPath);
        setLog.bSetPrintStrategy = 1;
        bLogopen = netsdk.CLIENT_LogOpen(setLog);
        if (!bLogopen) {
            System.err.println("Failed to open NetSDK log");
        }

        if (m_hAttachHandle.longValue() == 0) {
            System.err.printf("Attach Failed!LastError = %s\n", ToolKits.getErrorCodePrint());
            return m_hAttachHandle;
        }
        System.out.printf("Attach Succeed at Channel %d ! AttachHandle: %d. Wait Device Notify Information\n", channel, m_hAttachHandle.longValue());
        return m_hAttachHandle;
    }

    public static class HaveReConnectCallBack implements NetSDKLib.fHaveReConnect {
        private HaveReConnectCallBack() {
        }

        private static class CallBackHolder {
            private static HaveReConnectCallBack instance = new HaveReConnectCallBack();
        }

        public static HaveReConnectCallBack getInstance() {
            return HaveReConnectCallBack.CallBackHolder.instance;
        }

        public void invoke(NetSDKLib.LLong m_hLoginHandle, String pchDVRIP, int nDVRPort, Pointer dwUser) {
            System.out.printf("ReConnect Device[%s] Port[%d]\n", pchDVRIP, nDVRPort);

        }
    }


    public static class DisConnectCallBack implements NetSDKLib.fDisConnect {

        private DisConnectCallBack() {
        }

        private static class CallBackHolder {
            private static DisConnectCallBack instance = new DisConnectCallBack();
        }

        public static DisConnectCallBack getInstance() {
            return CallBackHolder.instance;
        }

        public void invoke(NetSDKLib.LLong lLoginID, String pchDVRIP, int nDVRPort, Pointer dwUser) {
            System.out.printf("Device[%s] Port[%d] DisConnect!\n", pchDVRIP, nDVRPort);
        }
    }


}
